<template>
  <div class="app-container">
    <div class="top-section-container">
      <div class="content-header">
        <h1>预约管理/<small>预约设置</small></h1>
        <el-breadcrumb class="breadcrumb" separator-class="el-icon-arrow-right">
          <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
          <el-breadcrumb-item>预约管理</el-breadcrumb-item>
          <el-breadcrumb-item>预约设置</el-breadcrumb-item>
        </el-breadcrumb>
      </div>
    </div>

    <div class="bottom-section-container">
      <div class="calendar-section">
        <div class="calendar-header">
          <el-button @click="pickPreMonth">上月</el-button>
          <el-button @click="goCurrentMonth" class="gotoday-button">本月</el-button>
          <el-button @click="pickNextMonth">下月</el-button>
          <span class="current-month-display year-month">{{ currentYear }} 年 {{ currentMonth }} 月</span>
        </div>
        <div class="calendar-wrapper">
          <div class="week-header">
            <span>周一</span><span>周二</span><span>周三</span><span>周四</span><span>周五</span><span>周六</span><span>周日</span>
          </div>
          <div class="days-grid">
            <div
                v-for="(day, index) in calendarDays"
                :key="index"
                :class="[
                'day-item',
                { 'is-current-month': day.isCurrentMonth },
                { 'is-fully-booked': day.orderSetting && day.orderSetting.number > 0 && day.orderSetting.number === day.orderSetting.reservations },
                { 'has-order-setting': day.orderSetting && !(day.orderSetting.number > 0 && day.orderSetting.number === day.orderSetting.reservations) }
              ]"
                @click="handleDayClick(day)"
            >
              <span class="day-number">{{ day.dayOfMonth }}</span>
              <div v-if="day.orderSetting" class="order-info">
                <p class="available-text">可预约: <span class="available">{{ day.orderSetting.number }}</span></p>
                <p class="reserved-text">已预约: <span class="reserved">{{ day.orderSetting.reservations }}</span></p>
              </div>
              <div v-else class="no-order-info calendar-p">
                <p>未设置</p>
              </div>
            </div>
          </div>
        </div>
      </div>
      <div class="box-footer">
        <el-button type="primary" @click="handleImportExcel">批量导入</el-button>
      </div>
    </div>

    <el-dialog
        v-model="dialogVisible"
        :title="dialogTitle"
        width="400px"
        @close="handleDialogClose"
    >
      <el-form :model="orderSettingForm" ref="orderSettingFormRef" label-width="120px">
        <el-form-item label="预约日期">
          <span>{{ orderSettingForm.orderDate }}</span>
        </el-form-item>
        <el-form-item label="最大预约人数" prop="number">
          <el-input-number
              v-model="orderSettingForm.number"
              :min="0"
              controls-position="right"
          ></el-input-number>
        </el-form-item>
        <el-form-item label="已预约人数">
          <span>{{ orderSettingForm.reservations }}</span>
        </el-form-item>
      </el-form>
      <template #footer>
          <span class="dialog-footer">
            <el-button @click="dialogVisible = false">取消</el-button>
            <el-button type="primary" @click="submitOrderSetting">确定</el-button>
          </span>
      </template>
    </el-dialog>

    <el-dialog
        v-model="importDialogVisible"
        title="批量导入预约设置"
        width="30%"
        class="center-dialog"
    >
      <el-upload
          class="upload-demo"
          action="/ordersetting/upload"
          :on-success="handleUploadSuccess"
          :on-error="handleUploadError"
          :before-upload="beforeUpload"
          name="excelFile"
      >
        <el-button type="primary">点击上传</el-button>
        <el-icon class="el-icon--upload"><upload-filled /></el-icon>
        <div class="el-upload__text">
          拖拽文件到此处或 <em>点击上传</em>
        </div>
        <template #tip>
          <div class="el-upload__tip">
            只能上传 xlsx 文件，且不超过 5MB。<br/>
            <el-link type="primary" @click="downloadTemplate">下载预约设置模板</el-link>
          </div>
        </template>
      </el-upload> <template #footer>
        <span class="dialog-footer">
          <el-button @click="importDialogVisible = false">取消</el-button>
        </span>
    </template>
    </el-dialog>

  </div>
</template>

<script setup>
import { ref, reactive, computed, onMounted } from 'vue';
import { ElMessage } from 'element-plus';
import { UploadFilled } from '@element-plus/icons-vue';
import axios from 'axios';
import moment from 'moment'; // Import moment for date formatting

// Current year and month for the calendar display
const currentYear = ref(new Date().getFullYear());
const currentMonth = ref(new Date().getMonth() + 1); // Month is 1-indexed

// Stores order setting data for the current month: { 'YYYY-MM-DD': { date: '...', number: 0, reservations: 0 } }
const monthlyOrderSettings = reactive({});

// Dialog for single day order setting
const dialogVisible = ref(false);
const dialogTitle = ref('预约设置');
const orderSettingForm = reactive({
  orderDate: '',
  number: 0, // Maps to 'number' from backend data (max available)
  reservations: 0, // Maps to 'reservations' from backend data (already booked), non-editable
});
const orderSettingFormRef = ref(null); // Form reference for validation (if needed)

// Dialog for batch import
const importDialogVisible = ref(false);

// Computed property for calendar days array
const calendarDays = computed(() => {
  const days = [];
  const firstDay = new Date(currentYear.value, currentMonth.value - 1, 1);
  const lastDay = new Date(currentYear.value, currentMonth.value, 0);

  // Get the day of the week for the first day of the month (0: Sunday, 1: Monday, ..., 6: Saturday)
  // Convert Sunday (0) to 7 for consistent calculation
  const startDayOfWeek = firstDay.getDay() === 0 ? 7 : firstDay.getDay();

  // Fill in the end of the previous month (placeholders) to align with Monday
  for (let i = 1; i < startDayOfWeek; i++) {
    days.push({ dayOfMonth: '', isCurrentMonth: false });
  }

  // Fill in the dates for the current month
  for (let i = 1; i <= lastDay.getDate(); i++) {
    const dateStr = `${currentYear.value}-${String(currentMonth.value).padStart(2, '0')}-${String(i).padStart(2, '0')}`;
    days.push({
      dayOfMonth: i,
      isCurrentMonth: true,
      fullDate: dateStr,
      orderSetting: monthlyOrderSettings[dateStr] || null, // Link with fetched data
    });
  }
  return days;
});

// Fetches order setting data for the specified month
const fetchOrderSetting = async () => {
  console.log(`Fetching order settings for ${currentYear.value}-${currentMonth.value}`);
  // 使用 moment 格式化月份参数，确保 YYYY-MM 格式
  const month = moment(`${currentYear.value}-${String(currentMonth.value).padStart(2, '0')}-01`).format('YYYY-MM');
  try {
    const res = await axios.get('/ordersetting/getOrderSettingByMonth?date=' + month);
    if (res.data.flag) {
      // Clear old data
      for (const key in monthlyOrderSettings) {
        delete monthlyOrderSettings[key];
      }
      // Populate new data
      res.data.data.forEach(item => {
        // Parse the date string to 'YYYY-MM-DD'
        // 这部分取决于后端返回的 orderDate 格式，如果后端返回 'YYYY-MM-DDTHH:mm:ss.SSSZ'，则 split('T')[0] 是正确的
        const dateKey = item.orderDate.split('T')[0];
        monthlyOrderSettings[dateKey] = item;
      });
    } else {
      ElMessage.error(res.data.message);
    }
  } catch (error) {
    console.error('获取预约设置失败:', error);
    ElMessage.error('获取预约设置失败');
  }
};

// Switch to the previous month
const pickPreMonth = () => {
  if (currentMonth.value === 1) {
    currentMonth.value = 12;
    currentYear.value--;
  } else {
    currentMonth.value--;
  }
  fetchOrderSetting();
};

// Switch to the next month
const pickNextMonth = () => {
  if (currentMonth.value === 12) {
    currentMonth.value = 1;
    currentYear.value++;
  } else {
    currentMonth.value++;
  }
  fetchOrderSetting();
};

// Go to the current month
const goCurrentMonth = () => {
  const today = new Date();
  currentYear.value = today.getFullYear();
  currentMonth.value = today.getMonth() + 1;
  fetchOrderSetting();
};

// Handle day click
const handleDayClick = (day) => {
  if (!day.isCurrentMonth || !day.fullDate) {
    return; // Do not process dates outside the current month or empty placeholders
  }
  dialogTitle.value = '预约设置 - ' + day.fullDate;
  Object.assign(orderSettingForm, {
    orderDate: day.fullDate, // day.fullDate 已经是 YYYY-MM-DD 字符串
    number: day.orderSetting ? day.orderSetting.number : 0,
    reservations: day.orderSetting ? day.orderSetting.reservations : 0,
  });
  dialogVisible.value = true;
};

// Submit order setting for a single day
const submitOrderSetting = async () => {
  try {
    const dataToSend = [{
      // 明确地将日期格式化为 YYYY-MM-DD 字符串，以确保后端接收到期望的格式
      orderDate: moment(orderSettingForm.orderDate).format('YYYY-MM-DD'),
      number: orderSettingForm.number,
      reservations: orderSettingForm.reservations, // Send back existing reservations
      id: monthlyOrderSettings[orderSettingForm.orderDate]?.id || null, // Include ID if updating an existing setting
    }];

    const res = await axios.post('/ordersetting/editReservations', dataToSend);

    if (res.data.flag) {
      ElMessage.success(res.data.message);
      dialogVisible.value = false;
      fetchOrderSetting(); // Reload data to update calendar display
    } else {
      ElMessage.error(res.data.message);
    }
  } catch (error) {
    ElMessage.error('操作异常');
    console.error(error);
  }
};

// Clear form validation status when dialog closes
const handleDialogClose = () => {
  // if (orderSettingFormRef.value) {
  //   orderSettingFormRef.value.resetFields();
  // }
};

// Batch import logic
const handleImportExcel = () => {
  importDialogVisible.value = true;
};

const handleUploadSuccess = (response, uploadFile) => {
  if (response.flag) {
    ElMessage.success(response.message);
    importDialogVisible.value = false;
    fetchOrderSetting(); // Refresh calendar data after successful import
  } else {
    ElMessage.error(response.message);
  }
};

const handleUploadError = (error, uploadFile) => {
  ElMessage.error('文件上传失败：' + error.message);
};

const beforeUpload = (file) => {
  const isXlsx = file.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
  const isLt5M = file.size / 1024 / 1024 < 5;

  if (!isXlsx) {
    ElMessage.error('上传文件只能是 xlsx 格式!');
  }
  if (!isLt5M) {
    ElMessage.error('上传文件大小不能超过 5MB!');
  }
  return isXlsx && isLt5M;
};

const downloadTemplate = async () => {
  try {
    const response = await axios.get('/ordersetting/downloadTemplate', {
      responseType: 'blob', // Explicitly set response type to blob
    });
    const url = window.URL.createObjectURL(new Blob([response.data]));
    const link = document.createElement('a');
    link.href = url;
    link.setAttribute('download', 'ordersetting_template.xlsx');
    document.body.appendChild(link);
    link.click();
    link.remove();
    window.URL.revokeObjectURL(url); // Release the URL object
    ElMessage.success('模板下载成功');
  } catch (error) {
    console.error('下载模板失败:', error);
    ElMessage.error('下载模板失败');
  }
};

// When component is mounted, load data for the current month
onMounted(() => {
  goCurrentMonth(); // Default to displaying current month's data
});
</script>

<style scoped>
/* Container basic styles, mimicking app-container */
.app-container {
  padding: 0; /* Outer container no padding, let inner sections control */
  box-sizing: border-box;
}

/* Top section styles */
.top-section-container {
  background-color: #f9f9f9; /* Light gray background */
  padding: 1.25rem 1.25rem 0.625rem; /* Inner padding */
  border-bottom: 3px solid #409EFF; /* Blue bottom border */
  margin-bottom: 1.25rem; /* Space from content area below */
  box-shadow: 0 2px 4px rgba(0,0,0,0.05); /* Bottom shadow */
}

/* Bottom content area styles */
.bottom-section-container {
  background-color: #ffffff; /* White background */
  padding: 1.25rem; /* Inner padding */
  box-shadow: 0 2px 4px rgba(0,0,0,0.05); /* Shadow */
  border-radius: 0.25rem; /* Rounded corners */
  margin: 0 1.25rem 1.25rem 1.25rem; /* Left, right and bottom margin */
}

/* Existing style adjustments */
.content-header {
  padding-bottom: 0.625rem; /* Keep space between breadcrumb and title */
}

/* Unify Element Plus input box internal styles, corresponding to .ordersetting .el-input__inner in orderset.css */
/* Note: .ordersetting as an external component class name might not work, change to global or more specific selector */
:deep(.el-input__inner),
:deep(.el-input-number__increase),
:deep(.el-input-number__decrease) {
  height: 36px;
  line-height: 36px;
}

.calendar-section {
  /* This block is now content of bottom-section-container, no longer needs extra background or border */
  /* background-color: #fff; */
  /* border: 1px solid #ebeef5; */
  border-radius: 4px;
  overflow: hidden;
}

/* Calendar header, remove styles previously added to simulate divider */
.calendar-header {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 10px 0; /* Adjust inner padding */
  background-color: #f5f7fa; /* Light gray background */
  border-bottom: none; /* Remove blue divider, provided by top-section-container */
  padding-bottom: 10px; /* Restore normal padding */
}

.current-month-display.year-month { /* Corresponds to .year-month in orderset.css */
  margin: 0 20px;
  font-size: 18px;
  font-weight: bold;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-around;
}

.current-month-display.year-month:hover { /* Corresponds to .year-month:hover in orderset.css */
  background: rgba(150, 2, 12, 0.1);
}

.gotoday-button { /* Corresponds to .gotoday in orderset.css */
  border: 1px solid #d5d9df;
}

/* Calendar grid */
.week-header {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  text-align: center;
  background-color: #f5f7fa;
  padding: 10px 0;
  font-weight: bold;
  border-bottom: 1px solid #ebeef5;
}

.days-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
}

.day-item {
  min-height: 100px;
  border: 1px solid #ebeef5;
  border-top: none;
  border-left: none;
  padding: 10px;
  cursor: pointer;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  align-items: flex-start;
  font-size: 14px;
  color: #606266;
  position: relative;
}

.day-item:nth-child(7n) {
  border-right: none;
}

.day-item:hover {
  background-color: #f2f6fc;
}

.day-item.is-current-month {
  background-color: #fff;
}

.day-item:not(.is-current-month) {
  color: #c0c4cc;
  background-color: #fcfcfc;
  cursor: default;
}

.day-item .day-number {
  position: absolute;
  top: 5px;
  right: 10px;
  font-size: 16px;
  font-weight: bold;
}

.order-info {
  width: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  height: calc(100% - 30px);
  margin-top: 20px;
  line-height: 1.2;
}

.order-info p {
  margin: 2px 0;
}

.day-item.is-fully-booked {
  background: #ff8a8a;
  color: #fff;
}

.day-item.is-fully-booked .day-number,
.day-item.is-fully-booked .order-info p,
.day-item.is-fully-booked .order-info span {
  color: #fff !important;
}

.order-info .available {
  color: #67c23a;
}

.order-info .reserved {
  color: #e6a23c;
}

.no-order-info p {
  color: #909399;
  text-align: center;
  width: 100%;
  margin-top: 30px;
}

.dialog-footer {
  text-align: right;
  margin-top: 1.25rem;
}

.app-container {
  padding: 1.25rem; /* 20px -> 1.25rem */
  background-color: #f0f2f5;
  min-height: calc(100vh - 3.125rem); /* 50px -> 3.125rem */
}

.top-section-container {
  background-color: #ffffff;
  padding: 1.25rem 1.25rem 0.625rem; /* 20px 20px 10px -> 1.25rem 1.25rem 0.625rem */
  border-bottom: 3px solid #409EFF;
  margin-bottom: 1.25rem; /* 20px -> 1.25rem */
  box-shadow: 0 2px 4px rgba(0,0,0,0.05);
}

.content-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 0.625rem; /* 10px -> 0.625rem */
}

.content-header h1 {
  font-size: 1.5rem; /* 24px -> 1.5rem */
  color: #303133;
  margin: 0;
}

.content-header small {
  font-size: 0.875rem; /* 14px -> 0.875rem */
  color: #909399;
  margin-left: 0.625rem; /* 10px -> 0.625rem */
}

.breadcrumb {
  font-size: 0.875rem; /* 14px -> 0.875rem */
}

.bottom-section-container {
  background-color: #ffffff;
  padding: 1.25rem; /* 20px -> 1.25rem */
  box-shadow: 0 2px 4px rgba(0,0,0,0.05);
  border-radius: 0.375rem; /* 6px -> 0.375rem */
  margin: 0 1.25rem 1.25rem 1.25rem;
}

.box {
  border: 1px solid #EBEEF5; /* Element UI border color */
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.06);
  border-radius: 0.25rem; /* 4px -> 0.25rem */
  margin-bottom: 1.25rem; /* 20px -> 1.25rem */
}

.box-body {
  padding: 1.25rem; /* 20px -> 1.25rem */
}

.box-footer {
  text-align: right;
  padding: 0.625rem 1.25rem; /* 10px 20px -> 0.625rem 1.25rem */
  border-top: 1px solid #EBEEF5;
  background-color: #F8F8F8;
}

/* Batch import upload area styles */
.upload-demo {
  text-align: center;
  padding: 1.25rem 0;
}

/* Centered dialog style */
.center-dialog .el-dialog__body {
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
}
</style>